ENH: Add multi-dimensional drag coefficient support (Cd as function of M, Re, α) #875
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Pull request type
Checklist
black rocketpy/ tests/) has passed locallypytest tests -m slow --runslow) have passed locallyCHANGELOG.mdhas been updated (if relevant)Current behavior
Drag coefficients are limited to 1D functions of Mach number. CFD simulations typically produce drag data varying with Reynolds number and angle of attack, which cannot be properly represented.
New behavior
Drag coefficients now support N-dimensional structured grids via
Function.from_grid(). Flight simulations automatically calculate and pass Reynolds number (from velocity, density, viscosity, rocket diameter) and angle of attack (from freestream velocity vectors in body frame) to multi-dimensional drag functions.Implementation
Function Class (
rocketpy/mathutils/function.py)from_grid()class method usingscipy.interpolate.RegularGridInterpolator'linear_grid'interpolation type with edge clamping (no extrapolation beyond bounds)Flight Class (
rocketpy/simulation/flight.py)__get_drag_coefficient()helper detecting function dimensionalityudot_rail1(),u_dot(),u_dot_generalized()to use helperRocket Class (
rocketpy/rocket/rocket.py)Usage Example
Testing
Function.from_grid()covering 1D/2D/3D grids, extrapolation, validationBreaking change
Existing 1D drag curves (Mach only) work unchanged. Multi-dimensional support is opt-in via
from_grid().Additional information
Resolves #874
CodeQL security scan: 0 alerts
Original prompt
This section details on the original issue you should resolve
<issue_title>ENH: Drag curve as a function of Re and alpha as well</issue_title>
<issue_description>Is your feature request related to a problem? Please describe.
As of now drag curve is a function of speed (or mach number). Since a lot of rocketeers use CFD simulations, it is expected that drag values won't be just a function of mach number. Drag of any body moving in fluid can depend on many major parameters. Some of them are listed below:
Re accounts for the viscous effects of the flow (skin friction vs. pressure drag). Reynolds number depends on velocity, characteristic length, air viscosity, and density, and is crucial for modeling drag at low speeds and during laminar-turbulent transitions. Non-zero angles of attack change the effective cross-sectional area and cause flow separation or vortex formation, increasing drag. Altitude or atmospheric variation can be handled by RocketPy separately to update Re or atmospheric data rather than being built directly into the drag curve.
Drag could be input as Cd(M, α) or Cd(M, Re, α).
Describe the solution you'd like
Additional context
It does not make sense that the drag curve will be given as an input of Cd=f(Re) or Cd=f(α). Physically these are not capturing the entire flow physics at the same accuracy at which Cd=f(M) does as mach number based effects like shock wave propagation become more important in rocket flights. May be still allow for single array functionality with Re and α but provide a note that the results may not be accurate!</issue_description>
<agent_instructions>Here is a specific, technical prompt you can use to delegate this issue to the GitHub Copilot agent. This prompt directs it to the correct implementation strategy we discussed (enhancing the
Functionclass).Optional Prompt for GitHub Copilot
Here is a specific prompt to guide the implementation for Issue #874.
1. Core Objective:$\alpha$ ).
Implement the enhancement described in issue #874. The goal is to allow the drag coefficient
Cdto be defined as a 3D function of Mach (M), Reynolds number (Re), and Angle of Attack (2. Implementation Location:
The primary changes must be made within the
rocketpy.Functionclass (inrocketpy/function.py). This is not just a change to theFlightorRocketclass; theFunctionclass itself must be enhanced to handle N-dimensional structured grid data.3. Add New Interpolation Method:
The current
shepardinterpolation is inefficient for structured CFD grids.interpolation='linear_grid'orinterpolation='grid') to theFunctionclass__init__.scipy.interpolate.RegularGridInterpolatoras its backend. You will need to import this fromscipy.interpolate.Functionclass state should store the initializedRegularGridInterpolatorobject to be called later.4. Add New
Function.from_grid()Class Method:Manually creating a flattened list of points is impractical for users.
@classmethod def from_grid(cls, grid_data, axes, inputs, output, interpolation='linear_grid', **kwargs).grid_data: An N-dimensional NumPy array (e.g., a 3D array foraxes: A list of 1D arrays representing the axes of the grid (e.g.,[M_axis, Re_axis, A_axis]).inputs: A list of strings, e.g.,['Mach', 'Reynolds', 'Alpha'].output: A string, e.g.,'Cd'.scipy.interpolate.RegularGridInterpolatorwith the providedaxesandgrid_dataand store it in the newFunctionobject.5. Handle Extrapolation (Crucial):
The new grid interpolation must clamp to the edge (i.e., use the nearest edge value) for out-of-bounds requests. It should not extrapolate.
RegularGridInterpolator, setbounds_error=False.fill_valueshould be set toNone, which (whenbounds_error=False) causes the interpolator to use the edge values for out-of-bounds points.6. Update Flight Class:
The
Flightclass (likely inflight.pyor related files) must be modified to use this new function.💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.